*
* @covers WatchedItemStore
*/
-class WatchedItemStoreUnitTest extends PHPUnit_Framework_TestCase {
+class WatchedItemStoreUnitTest extends MediaWikiTestCase {
/**
* @return PHPUnit_Framework_MockObject_MockObject|IDatabase
/**
* @return PHPUnit_Framework_MockObject_MockObject|LoadBalancer
*/
- private function getMockLoadBalancer( $mockDb ) {
+ private function getMockLoadBalancer( $mockDb, $expectedConnectionType = null ) {
$mock = $this->getMockBuilder( LoadBalancer::class )
->disableOriginalConstructor()
->getMock();
- $mock->expects( $this->any() )
- ->method( 'getConnection' )
- ->will( $this->returnValue( $mockDb ) );
+ if ( $expectedConnectionType !== null ) {
+ $mock->expects( $this->any() )
+ ->method( 'getConnection' )
+ ->with( $expectedConnectionType )
+ ->will( $this->returnValue( $mockDb ) );
+ } else {
+ $mock->expects( $this->any() )
+ ->method( 'getConnection' )
+ ->will( $this->returnValue( $mockDb ) );
+ }
$mock->expects( $this->any() )
->method( 'getReadOnlyReason' )
->will( $this->returnValue( false ) );
return $fakeRow;
}
+ private function newWatchedItemStore( LoadBalancer $loadBalancer, HashBagOStuff $cache ) {
+ return new WatchedItemStore(
+ $loadBalancer,
+ $cache
+ );
+ }
+
public function testGetDefaultInstance() {
$instanceOne = WatchedItemStore::getDefaultInstance();
$instanceTwo = WatchedItemStore::getDefaultInstance();
$this->assertSame( $instanceOne, $instanceTwo );
}
- public function testOverrideDefaultInstance() {
- $instance = WatchedItemStore::getDefaultInstance();
- $scopedOverride = $instance->overrideDefaultInstance( null );
-
- $this->assertNotSame( $instance, WatchedItemStore::getDefaultInstance() );
-
- unset( $scopedOverride );
-
- $this->assertSame( $instance, WatchedItemStore::getDefaultInstance() );
- }
-
public function testCountWatchedItems() {
$user = $this->getMockNonAnonUserWithId( 1 );
$mockCache->expects( $this->never() )->method( 'set' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'set' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'set' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'set' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'get' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'set' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'set' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'set' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'get' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'get' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'get' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
)
->will( $this->returnValue( new FakeResultWrapper( [] ) ) );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$this->getMockCache()
);
$mockCache->expects( $this->never() )->method( 'get' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'get' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'get' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
->method( 'delete' )
->with( '0:Some_Page:1' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )
->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
);
}
- public function testAddWatchBatch_nonAnonymousUser() {
+ public function testAddWatchBatchForUser_nonAnonymousUser() {
$mockDb = $this->getMockDb();
$mockDb->expects( $this->once() )
->method( 'insert' )
->method( 'delete' )
->with( '1:Some_Page:1' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockUser = $this->getMockNonAnonUserWithId( 1 );
$this->assertTrue(
- $store->addWatchBatch(
- [
- [ $mockUser, new TitleValue( 0, 'Some_Page' ) ],
- [ $mockUser, new TitleValue( 1, 'Some_Page' ) ],
- ]
- )
- );
- }
-
- public function testAddWatchBatch_anonymousUserCombinationsAreSkipped() {
- $mockDb = $this->getMockDb();
- $mockDb->expects( $this->once() )
- ->method( 'insert' )
- ->with(
- 'watchlist',
- [
- [
- 'wl_user' => 1,
- 'wl_namespace' => 0,
- 'wl_title' => 'Some_Page',
- 'wl_notificationtimestamp' => null,
- ]
- ]
- );
-
- $mockCache = $this->getMockCache();
- $mockCache->expects( $this->once() )
- ->method( 'delete' )
- ->with( '0:Some_Page:1' );
-
- $store = new WatchedItemStore(
- $this->getMockLoadBalancer( $mockDb ),
- $mockCache
- );
-
- $this->assertTrue(
- $store->addWatchBatch(
- [
- [ $this->getMockNonAnonUserWithId( 1 ), new TitleValue( 0, 'Some_Page' ) ],
- [ $this->getAnonUser(), new TitleValue( 0, 'Other_Page' ) ],
- ]
+ $store->addWatchBatchForUser(
+ $mockUser,
+ [ new TitleValue( 0, 'Some_Page' ), new TitleValue( 1, 'Some_Page' ) ]
)
);
}
- public function testAddWatchBatchReturnsFalse_whenOnlyGivenAnonymousUserCombinations() {
+ public function testAddWatchBatchForUser_anonymousUsersAreSkipped() {
$mockDb = $this->getMockDb();
$mockDb->expects( $this->never() )
->method( 'insert' );
$mockCache->expects( $this->never() )
->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
- $anonUser = $this->getAnonUser();
$this->assertFalse(
- $store->addWatchBatch(
- [
- [ $anonUser, new TitleValue( 0, 'Some_Page' ) ],
- [ $anonUser, new TitleValue( 1, 'Other_Page' ) ],
- ]
+ $store->addWatchBatchForUser(
+ $this->getAnonUser(),
+ [ new TitleValue( 0, 'Other_Page' ) ]
)
);
}
- public function testAddWatchBatchReturnsFalse_whenGivenEmptyList() {
+ public function testAddWatchBatchReturnsTrue_whenGivenEmptyList() {
+ $user = $this->getMockNonAnonUserWithId( 1 );
$mockDb = $this->getMockDb();
$mockDb->expects( $this->never() )
->method( 'insert' );
$mockCache->expects( $this->never() )
->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
- $this->assertFalse(
- $store->addWatchBatch( [] )
+ $this->assertTrue(
+ $store->addWatchBatchForUser( $user, [] )
);
}
'0:SomeDbKey:1'
);
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'get' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'get' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
->method( 'delete' )
->with( '0:SomeDbKey:1' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
->method( 'delete' )
->with( '0:SomeDbKey:1' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )
->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
'0:SomeDbKey:1'
);
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
)
->will( $this->returnValue( $cachedItem ) );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
->with( '0:SomeDbKey:1' )
->will( $this->returnValue( false ) );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'get' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
);
}
+ public function testGetWatchedItemsForUser() {
+ $mockDb = $this->getMockDb();
+ $mockDb->expects( $this->once() )
+ ->method( 'select' )
+ ->with(
+ 'watchlist',
+ [ 'wl_namespace', 'wl_title', 'wl_notificationtimestamp' ],
+ [ 'wl_user' => 1 ]
+ )
+ ->will( $this->returnValue( [
+ $this->getFakeRow( [
+ 'wl_namespace' => 0,
+ 'wl_title' => 'Foo1',
+ 'wl_notificationtimestamp' => '20151212010101',
+ ] ),
+ $this->getFakeRow( [
+ 'wl_namespace' => 1,
+ 'wl_title' => 'Foo2',
+ 'wl_notificationtimestamp' => null,
+ ] ),
+ ] ) );
+
+ $mockCache = $this->getMockCache();
+ $mockCache->expects( $this->never() )->method( 'delete' );
+ $mockCache->expects( $this->never() )->method( 'get' );
+ $mockCache->expects( $this->never() )->method( 'set' );
+
+ $store = $this->newWatchedItemStore(
+ $this->getMockLoadBalancer( $mockDb ),
+ $mockCache
+ );
+ $user = $this->getMockNonAnonUserWithId( 1 );
+
+ $watchedItems = $store->getWatchedItemsForUser( $user );
+
+ $this->assertInternalType( 'array', $watchedItems );
+ $this->assertCount( 2, $watchedItems );
+ foreach ( $watchedItems as $watchedItem ) {
+ $this->assertInstanceOf( 'WatchedItem', $watchedItem );
+ }
+ $this->assertEquals(
+ new WatchedItem( $user, new TitleValue( 0, 'Foo1' ), '20151212010101' ),
+ $watchedItems[0]
+ );
+ $this->assertEquals(
+ new WatchedItem( $user, new TitleValue( 1, 'Foo2' ), null ),
+ $watchedItems[1]
+ );
+ }
+
+ public function provideDbTypes() {
+ return [
+ [ false, DB_SLAVE ],
+ [ true, DB_MASTER ],
+ ];
+ }
+
+ /**
+ * @dataProvider provideDbTypes
+ */
+ public function testGetWatchedItemsForUser_optionsAndEmptyResult( $forWrite, $dbType ) {
+ $mockDb = $this->getMockDb();
+ $mockCache = $this->getMockCache();
+ $mockLoadBalancer = $this->getMockLoadBalancer( $mockDb, $dbType );
+ $user = $this->getMockNonAnonUserWithId( 1 );
+
+ $mockDb->expects( $this->once() )
+ ->method( 'select' )
+ ->with(
+ 'watchlist',
+ [ 'wl_namespace', 'wl_title', 'wl_notificationtimestamp' ],
+ [ 'wl_user' => 1 ],
+ $this->isType( 'string' ),
+ [ 'ORDER BY' => [ 'wl_namespace ASC', 'wl_title ASC' ] ]
+ )
+ ->will( $this->returnValue( [] ) );
+
+ $store = $this->newWatchedItemStore(
+ $mockLoadBalancer,
+ $mockCache
+ );
+
+ $watchedItems = $store->getWatchedItemsForUser(
+ $user,
+ [ 'forWrite' => $forWrite, 'sort' => WatchedItemStore::SORT_ASC ]
+ );
+ $this->assertEquals( [], $watchedItems );
+ }
+
+ public function testGetWatchedItemsForUser_badSortOptionThrowsException() {
+ $store = $this->newWatchedItemStore(
+ $this->getMockLoadBalancer( $this->getMockDb() ),
+ $this->getMockCache()
+ );
+
+ $this->setExpectedException( 'InvalidArgumentException' );
+ $store->getWatchedItemsForUser(
+ $this->getMockNonAnonUserWithId( 1 ),
+ [ 'sort' => 'foo' ]
+ );
+ }
+
public function testIsWatchedItem_existingItem() {
$mockDb = $this->getMockDb();
$mockDb->expects( $this->once() )
'0:SomeDbKey:1'
);
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
->with( '0:SomeDbKey:1' )
->will( $this->returnValue( false ) );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'get' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'set' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'set' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'set' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'set' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache = $this->getMockCache();
$mockCache->expects( $this->never() )->method( $this->anything() );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'set' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'set' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
->method( 'delete' )
->with( '0:SomeDbKey:1' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockDb->expects( $this->never() )
->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockDb->expects( $this->never() )
->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockDb->expects( $this->never() )
->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'get' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
$mockCache->expects( $this->never() )->method( 'get' );
$mockCache->expects( $this->never() )->method( 'delete' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);
->method( 'delete' )
->with( '0:SomeDbKey:1' );
- $store = new WatchedItemStore(
+ $store = $this->newWatchedItemStore(
$this->getMockLoadBalancer( $mockDb ),
$mockCache
);